[IA64] Avoid dom0 insufficient memory panic when creating guests
authorawilliam@xenbuild2.aw <awilliam@xenbuild2.aw>
Tue, 23 Jan 2007 16:08:03 +0000 (09:08 -0700)
committerawilliam@xenbuild2.aw <awilliam@xenbuild2.aw>
Tue, 23 Jan 2007 16:08:03 +0000 (09:08 -0700)
When there is not enough memory to create a domain,
we need not panic domain0. Just prevent it from creating.

Signed-off-by: Zhang Xin <xing.z.zhang@intel.com>
xen/arch/ia64/vmx/vmmu.c
xen/arch/ia64/vmx/vmx_init.c
xen/arch/ia64/xen/domain.c
xen/include/asm-ia64/vmmu.h
xen/include/asm-ia64/vmx.h

index aaf40556740616e1926eb3cc4719a80281a98f77..145cd4c4472b8781f5e21f5e95a17df54f7a0a81 100644 (file)
@@ -129,13 +129,15 @@ purge_machine_tc_by_domid(domid_t domid)
 #endif
 }
 
-static void init_domain_vhpt(struct vcpu *v)
+static int init_domain_vhpt(struct vcpu *v)
 {
     struct page_info *page;
     void * vbase;
     page = alloc_domheap_pages (NULL, VCPU_VHPT_ORDER, 0);
     if ( page == NULL ) {
-        panic_domain(vcpu_regs(v),"No enough contiguous memory for init_domain_vhpt\n");
+        printk("No enough contiguous memory for init_domain_vhpt\n");
+
+        return -1;
     }
     vbase = page_to_virt(page);
     memset(vbase, 0, VCPU_VHPT_SIZE);
@@ -147,18 +149,36 @@ static void init_domain_vhpt(struct vcpu *v)
     VHPT(v,cch_sz) = VCPU_VHPT_SIZE - VHPT(v,hash_sz);
     thash_init(&(v->arch.vhpt),VCPU_VHPT_SHIFT-1);
     v->arch.arch_vmx.mpta = v->arch.vhpt.pta.val;
+
+    return 0;
 }
 
 
+static void free_domain_vhpt(struct vcpu *v)
+{
+    struct page_info *page;
 
-void init_domain_tlb(struct vcpu *v)
+    if (v->arch.vhpt.hash) {
+        page = virt_to_page(v->arch.vhpt.hash);
+        free_domheap_pages(page, VCPU_VHPT_ORDER);
+    }
+
+    return;
+}
+
+int init_domain_tlb(struct vcpu *v)
 {
     struct page_info *page;
     void * vbase;
-    init_domain_vhpt(v);
+
+    if (init_domain_vhpt(v) != 0)
+        return -1;
+
     page = alloc_domheap_pages (NULL, VCPU_VTLB_ORDER, 0);
     if ( page == NULL ) {
-        panic_domain(vcpu_regs(v),"No enough contiguous memory for init_domain_tlb\n");
+        printk("No enough contiguous memory for init_domain_tlb\n");
+        free_domain_vhpt(v);
+        return -1;
     }
     vbase = page_to_virt(page);
     memset(vbase, 0, VCPU_VTLB_SIZE);
@@ -169,8 +189,11 @@ void init_domain_tlb(struct vcpu *v)
     VTLB(v,cch_buf) = (void *)((u64)vbase + VTLB(v,hash_sz));
     VTLB(v,cch_sz) = VCPU_VTLB_SIZE - VTLB(v,hash_sz);
     thash_init(&(v->arch.vtlb),VCPU_VTLB_SHIFT-1);
+    
+    return 0;
 }
 
+
 void free_domain_tlb(struct vcpu *v)
 {
     struct page_info *page;
@@ -179,10 +202,8 @@ void free_domain_tlb(struct vcpu *v)
         page = virt_to_page(v->arch.vtlb.hash);
         free_domheap_pages(page, VCPU_VTLB_ORDER);
     }
-    if ( v->arch.vhpt.hash) {
-        page = virt_to_page(v->arch.vhpt.hash);
-        free_domheap_pages(page, VCPU_VHPT_ORDER);
-    }
+
+    free_domain_vhpt(v);
 }
 
 /*
index c4cb0150ea3282644a5ac9619dcf06f987af4035..2ae82ed0869a42f514e6c16d384023f289a04999 100644 (file)
@@ -290,7 +290,7 @@ static void vmx_release_assist_channel(struct vcpu *v)
  * Initialize VMX envirenment for guest. Only the 1st vp/vcpu
  * is registered here.
  */
-void
+int
 vmx_final_setup_guest(struct vcpu *v)
 {
        vpd_t *vpd;
@@ -305,7 +305,8 @@ vmx_final_setup_guest(struct vcpu *v)
         * to this solution. Maybe it can be deferred until we know created
         * one as vmx domain */
 #ifndef HASH_VHPT
-       init_domain_tlb(v);
+       if (init_domain_tlb(v) != 0)
+               return -1;
 #endif
        vmx_create_event_channels(v);
 
@@ -322,6 +323,8 @@ vmx_final_setup_guest(struct vcpu *v)
 
        /* Set up guest 's indicator for VTi domain*/
        set_bit(ARCH_VMX_DOMAIN, &v->arch.arch_vmx.flags);
+
+       return 0;
 }
 
 void
index dc4ead671f0338c4b0333e43d72a0b804b198f19..c0b00e83d34708ba0203f5733961517505f71c36 100644 (file)
@@ -585,9 +585,11 @@ int arch_set_info_guest(struct vcpu *v, vcpu_guest_context_u c)
        if (test_bit(_VCPUF_initialised, &v->vcpu_flags))
                return 0;
 
-       if (d->arch.is_vti)
-               vmx_final_setup_guest(v);
-       else {
+       if (d->arch.is_vti) {
+               rc = vmx_final_setup_guest(v);
+               if (rc != 0)
+                       return rc;
+       } else {
                rc = vcpu_late_initialise(v);
                if (rc != 0)
                        return rc;
index 4b86a33711c5ee4905e04f9a2a28ded201aabec3..9c436ce0e6dab781177c14d2279374a92a79e151 100644 (file)
@@ -295,7 +295,7 @@ extern u64 machine_thash(PTA pta, u64 va);
 extern void purge_machine_tc_by_domid(domid_t domid);
 extern void machine_tlb_insert(struct vcpu *d, thash_data_t *tlb);
 extern ia64_rr vmmu_get_rr(struct vcpu *vcpu, u64 va);
-extern void init_domain_tlb(struct vcpu *d);
+extern int init_domain_tlb(struct vcpu *d);
 extern void free_domain_tlb(struct vcpu *v);
 extern thash_data_t * vsa_thash(PTA vpta, u64 va, u64 vrr, u64 *tag);
 extern thash_data_t * vhpt_lookup(u64 va);
index 4e0971278a70f640225ee14ed97e273056a92d7c..5cd0e8c9bf6fc8d3bceb196bcb045fd4c8fa80aa 100644 (file)
@@ -31,7 +31,7 @@
 extern void identify_vmx_feature(void);
 extern unsigned int vmx_enabled;
 extern void vmx_init_env(void);
-extern void vmx_final_setup_guest(struct vcpu *v);
+extern int vmx_final_setup_guest(struct vcpu *v);
 extern void vmx_save_state(struct vcpu *v);
 extern void vmx_load_state(struct vcpu *v);
 extern void vmx_setup_platform(struct domain *d);